<?php
declare(strict_types=1);

namespace App\Logic;

use App\Event\AdministratorLogsEvent;
use App\Models\Menu as MenuModel;
use Illuminate\Support\Facades\DB;

class Menu
{
    public function list()
    {
        return MenuModel::select('id','pid','menu_type','menu_name','menu_url','menu_icon','menu_status','menu_sort')->orderBy('menu_sort','asc')->get();
    }

    public function count(): int
    {
        return MenuModel::count();
    }

    public function getMenu(int $pid = 0): array
    {
        return MenuModel::select('id','menu_name','menu_icon','menu_url as href')->where([['menu_type', '=', 2],['pid', '=', $pid]])->orderBy('menu_sort')->get()->toArray();
    }

    public function countMenu(int $pid = 0): int
    {
        return MenuModel::where([['menu_type', '=', 2],['pid', '=', $pid]])->count();
    }

    public function subCount(int $pid = 0): int
    {
        return MenuModel::where('pid', '=', $pid)->count();
    }

    public function sub(int $pid = 0): array
    {
        return MenuModel::select('id','menu_name')->where('pid', '=', $pid)->orderBy('menu_sort')->get()->toArray();
    }

    public function sub2arr(int $pid = 0, &$result = []): array
    {
        $subData = $this->sub($pid);
        if ($subData) {
            foreach ($subData as $k => $v) {
                if ($this->subCount($v['id']) > 0) {
                    $v['child'] = $this->sub2arr($v['id']);
                } else {
                    $v['child'] = [];
                }
                $result[] = $v;
            }
        }
        return $result;
    }

    public function add(array $data): bool
    {
        $model = new MenuModel;
        foreach ($data as $k => $v) {
            $model->$k = $v;
        }
        if ($model->save($data)) {
            event(new AdministratorLogsEvent("添加后台菜单"));
            return true;
        }
        return false;
    }

    public function update(int $id, array $data): bool
    {
        $model = MenuModel::find($id);
        foreach ($data as $k => $v) {
            $model->$k = $v;
        }
        if ($model->save()) {
            event(new AdministratorLogsEvent("修改后台菜单"));
            return true;
        }
        return false;
    }

    public function status(int $id): bool
    {
        $model = MenuModel::find($id);
        $model->menu_status = $model->menu_status == 1 ? 2 : 1;
        if ($model->save()) {
            event(new AdministratorLogsEvent("修改后台菜单状态"));
            return true;
        }
        return false;
    }

    public function delete(int $id): bool
    {
        $model = MenuModel::find($id);
        DB::beginTransaction();
        try {
            $model->roles()->detach();
            $model->delete();
            DB::commit();
            event(new AdministratorLogsEvent("删除后台菜单"));
            return true;
        } catch (\Exception $e) {
            DB::rollBack();
            return false;
        }
    }

    public function checkName(string $name, int $pid = 0, int $id = 0): bool
    {
        $model = MenuModel::where([['menu_name', '=', $name], ['pid', '=', $pid], ['id', '<>', $id]])->first();
        if (empty($model)) return true;
        return false;
    }

    public function checkUrl(string $url, int $id = 0): bool
    {
        $model = MenuModel::where([['menu_url', '=', $url], ['id', '<>', $id]])->first();
        if (empty($model)) return true;
        return false;
    }

    public function find(int $id = 0)
    {
        return MenuModel::find($id);
    }

    public function has(int $id = 0)
    {
        $model = MenuModel::find($id);
        if (empty($model)) return false;
        return true;
    }

    public function countRoleByMenuId(int $id = 0): int
    {
        $menu = MenuModel::find($id);
        $roles = $menu->roles;
        return $roles->count();
    }
}
